import React, { useState, useEffect } from 'react';
import { connect, Dispatch } from 'umi';
import { Space, Tag } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import { PageContainer } from '@ant-design/pro-layout';
import ProCard from '@ant-design/pro-card';
import { MENU_INIT, MENU_LIST, MENU_ADD, MENU_UPDATE, MENU_DELETE, MENU_UNMOUNT } from '@/actions/menu';
import AGrid, { AGridButtonCallBackModel } from '@/components/SelfComp/AGrid';
import { ConnectState } from '@/models/connect';
import { DataItem, FlagEnum } from '@/types/global';
import { MenuItem, MenuSelectTreeItem } from '@/types/menu';
import { getItemValue } from '@/utils/commons';
import MenuQueryForm from './components/MenuQueryForm';
import AddMenuModal from './components/AddMenuModal';
import UpdateMenuModal from './components/UpdateMenuModal';

interface MenuListProps {
  dispatch: Dispatch;
  menuList: MenuItem[],
  total: number,
  loading: boolean;
  pageSize: number;
  addLoading: boolean;
  updateLoading: boolean;
  menuTypeData: DataItem[];
  menuActionData: DataItem[];
  statusData: DataItem[];
  hideInMenuData: DataItem[];
}

const EMPTY: MenuItem = {
  menuId: '',
  parentMenuId: '',
  menuCode: '',
  menuName: '',
  menuPath: '',
  menuType: '',
  hideInMenu: '',
  menuStates: '',
  menuAction: '',
  menuSort: '',
  menuAlias: '',
  children: []
}

const MenuList: React.FC<MenuListProps> = (props) => {
  // 新增弹窗
  const [addModalVisible, setAddModalVisible] = useState<boolean>(false);
  const [menuFormData, setMenuFormData] = useState<MenuItem>(EMPTY);
  const [updateModalVisible, setUpdateModalVisible] = useState<boolean>(false);
  const [selectedRows, setSelectedRows] = useState<MenuItem[]>([]);
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  const [queryParam, setQueryParam] = useState<MenuItem>();
  const [flag, setFlag] = useState<FlagEnum>('edit');

  useEffect(() => {
    console.info('MenuList.useEffect');
    // 查询本页面需所有参数
    const { dispatch } = props;
    dispatch(MENU_INIT({}));
    return () => {
      dispatch(MENU_UNMOUNT({}));
    }
  }, []);

  const columns: ColumnsType<MenuItem> = [
    {
      title: '菜单权限名称',
      dataIndex: 'menuName',
      width: 180
    },
    {
      title: '菜单图标',
      dataIndex: 'menuIcon',
      width: 200,
      ellipsis: true
    },
    {
      title: '菜单权限编码',
      dataIndex: 'menuCode',
      width: 130
    },
    {
      title: '菜单权限别名',
      dataIndex: 'menuAlias',
      width: 120
    },
    {
      title: '菜单权限类型',
      dataIndex: 'menuType',
      render: (text: string, record: MenuItem, index: number) => menuTypeFunc(record),
      width: 100
    },
    {
      title: '菜单是否显示',
      dataIndex: 'hideInMenu',
      render: (text: string, record: MenuItem, index: number) => hideInMenuFunc(record),
      width: 100
    },
    {
      title: '路由地址',
      dataIndex: 'menuPath',
      width: 250,
      ellipsis: true
    },
    {
      title: '按钮位置',
      dataIndex: 'menuAction',
      render: (text: string, record: MenuItem, index: number) => menuActionFunc(record),
      width: 100
    },
    {
      title: '排序',
      dataIndex: 'menuSort',
      width: 60
    }
  ];

  const menuTypeFunc = (record: MenuItem) => {
    const { menuTypeData } = props;
    const { menuType } = record;
    const value = getItemValue(menuTypeData, menuType);
    if (menuType === '2') {
      return <Tag color='error'>{value}</Tag>;
    }
    return <Tag color='processing'>{value}</Tag>
  }

  const hideInMenuFunc = (record: MenuItem) => {
    const { hideInMenuData } = props;
    const { hideInMenu } = record;
    const value = getItemValue(hideInMenuData, hideInMenu);
    if (hideInMenu === '1') {
      return <Tag color='error'>{value}</Tag>;
    }
    return <Tag color='processing'>{value}</Tag>;
  }

  const menuActionFunc = (record: MenuItem) => {
    const { menuActionData } = props;
    const { menuAction } = record;
    if (!menuAction) {
      return '';
    }
    const value = getItemValue(menuActionData, menuAction);
    return <Tag color='processing'>{value}</Tag>
  }

  /**
   * 打开菜单新增窗口
   */
  const openAddMenuModal = () => {
    if (selectedRowKeys && selectedRowKeys.length == 1) {
      // 把勾选的节点当上级节点
      // 判断是否为菜单或弹窗
      const row = selectedRows[0];
      setMenuFormData({
        ...row
      });
    }
    setAddModalVisible(true);
  }

  /**
   * 修改菜单，打开菜单修改窗口
   */
  const openUpdateMenuModal = (record: MenuItem[], flag: FlagEnum) => {
    // 表格选中内容
    // console.info('openUpdateMenuModal');
    // console.info(record);
    const row = record[0];
    const menuFormData = {
      ...row,
    };
    setMenuFormData(menuFormData);
    setFlag(flag);
    setUpdateModalVisible(true);
  }

  const handleAddModalOk = async (record: MenuItem) => {
    // console.log(record);
    const { dispatch } = props;
    const res = await dispatch(MENU_ADD(record));
    console.info(res);
    if (res) {
      setAddModalVisible(false);
      setMenuFormData(EMPTY);
      const { pageSize } = props;
      fetchAllMenu(1, pageSize);
    }
  }

  const handleAddModalCancel = () => {
    setAddModalVisible(false);
  };

  const handleUpdateModalOk = async (record: MenuItem) => {
    // console.log('handleUpdateModalOk');
    // console.log(record);
    if (flag === 'edit') {
      const { dispatch } = props;
      const res = await dispatch(MENU_UPDATE(record));
      console.info(res);
      if (res) {
        setUpdateModalVisible(false);
        setMenuFormData(EMPTY);
        const { pageSize } = props;
        fetchAllMenu(1, pageSize);
      }
    } else {
      setUpdateModalVisible(false);
      setMenuFormData(EMPTY);
    }
  }

  const handleUpdateModalCancel = () => {
    setUpdateModalVisible(false);
    setMenuFormData(EMPTY);
  };

  const deleteMenus = async (keys: React.Key[]) => {
    const { dispatch } = props;
    const res = await dispatch(MENU_DELETE(keys));
    if (res) {
      const { pageSize } = props;
      fetchAllMenu(1, pageSize);
    }
  }

  /**
   * 根据条件分页查询表格数据
   * @param {*} record 条件
   */
  const handleFetchMenu = (record: MenuItem) => {
    console.log(record);
    const queryParam = {
      ...record
    };
    // 查询条件保存起来，方便点击页码时使用
    setQueryParam(queryParam);
    const { pageSize } = props;
    fetchAllMenu(1, pageSize);
  }

  /**
   * 查询菜单树信息
   * @param {*} pageSize 每页记录条数
   * @param {*} pageNum 页码
   */
  const fetchAllMenu = (pageNum: number, pageSize: number) => {
    const { dispatch } = props;
    dispatch(MENU_LIST({
      ...queryParam,
      pageSize,
      pageNum
    }));
  }

  /**
   * 处理按钮点击回调事件
   * @param {*} payload 数据包
   */
  const handleBtnCallBack = (callBackModel: AGridButtonCallBackModel<MenuItem>) => {
    // btn 按钮
    // keys 表格勾选数组
    const { code, keys } = callBackModel;
    // 新增
    if (code === 'add') {
      openAddMenuModal();
      return;
    }
    // 修改
    if (code === 'edit') {
      const { rows } = callBackModel;
      openUpdateMenuModal(rows, 'edit');
      return;
    }
    // 删除
    if (code === 'delete') {
      // const { rows } = callBackModel;
      // 调用删除服务，删除勾选数据
      deleteMenus(keys);
      return;
    }
    // 查看
    if (code === 'view') {
      const { rows } = callBackModel;
      openUpdateMenuModal(rows, 'view');
      return;
    }
  }

  /**
   * 表格勾选回调函数
   * @param {*} rows 表格选中数据集合
   */
  const onSelectRow = (keys: React.Key[], rows: MenuItem[]) => {
    setSelectedRows(rows);
    setSelectedRowKeys(keys);
  };

  /**
   * 根据全量菜单数据生成下拉框菜单树形数据，过滤掉按钮
   * @param {Array} menuList 全量菜单数据
   * @returns 下拉框菜单树形数据
   */
  const generatorMenuTreeData = (menuList: MenuItem[] = []): MenuSelectTreeItem[] => {
    return menuList.map(menu => {
      if (menu.children) {
        const newMenu: MenuSelectTreeItem = {
          value: menu.menuId,
          title: menu.menuName,
          children: generatorMenuTreeData(menu.children.filter(childMenu => childMenu.menuType === '0' || childMenu.menuType === '1' || childMenu.menuType === '3'))
        };
        return newMenu;
      } else {
        const newMenu: MenuSelectTreeItem = {
          value: menu.menuId,
          title: menu.menuName
        };
        return newMenu;
      }
    });
  }

  const code = 'menu-list';
  const { menuList, loading, menuTypeData, menuActionData, hideInMenuData, addLoading, updateLoading } = props;
  // menuList过滤掉按钮，只保留菜单
  const menuTreeData = generatorMenuTreeData(menuList);
  const rowKey = (record: MenuItem) => record.menuId;
  const pkField = 'menuId';

  return (
    <PageContainer>
        <Space direction='vertical' size='middle' style={{ display: 'flex' }}>
          <ProCard title='查询条件' headerBordered >
            <MenuQueryForm colon={false} onSubmit={handleFetchMenu} loading={loading}/>
          </ProCard>
          <ProCard>
            <AGrid
              code={code}
              btnCallBack={handleBtnCallBack}
              columns={columns}
              rowKey={rowKey}
              pkField={pkField}
              dataSource={menuList}
              loading={loading}
              onSelectRow={onSelectRow}
              scroll={{x:1600}}
              actionColumnFixed={'right'}
            />
          </ProCard>
        </Space>
        {
          !addModalVisible ? null :
          <AddMenuModal
            menuTypeData={menuTypeData}
            menuActionData={menuActionData}
            hideInMenuData={hideInMenuData}
            menuTreeData={menuTreeData}
            colon={false}
            modalTitle='新增菜单权限'
            modalWidth={1000}
            modalVisible={addModalVisible}
            loading={addLoading}
            formData={menuFormData}
            onHandlerOK={handleAddModalOk}
            onHandlerCancel={handleAddModalCancel}
          />
        }
        {
          !updateModalVisible ? null :
          <UpdateMenuModal
            menuTypeData={menuTypeData}
            menuActionData={menuActionData}
            hideInMenuData={hideInMenuData}
            menuTreeData={menuTreeData}
            colon={false}
            modalTitle=''
            modalWidth={1000}
            modalVisible={updateModalVisible}
            flag={flag}
            loading={updateLoading}
            formData={menuFormData}
            onHandlerOK={handleUpdateModalOk}
            onHandlerCancel={handleUpdateModalCancel}
          />
        }
    </PageContainer>
  );
}

export default connect(({ menus, loading }: ConnectState) => ({
  ...menus,
  loading: loading.effects['menus/fetchAllMenu'] || loading.effects['menus/deleteMenus'],
  addLoading: loading.effects['menus/addMenu'],
  updateLoading: loading.effects['menus/updateMenu'],
}))(MenuList);